package com.bigdatan.b2c.upload.glass;


import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.PutObjectResult;
import com.bigdatan.b2c.controller.AbstractController;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import util.JsonResponse;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * Created by yonney on 17/5/10.
 */
@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/api/image")
public class ImageController extends AbstractController {

    // endpoint以杭州为例，其它region请按实际情况填写
    //oss-cn-shenzhen.aliyuncs.com	oss-cn-shenzhen-internal.aliyuncs.com
    public static final String endpoint = "oss-cn-shenzhen.aliyuncs.com";

    public static final String neiwang_endpoint = "oss-cn-shenzhen-internal.aliyuncs.com";
    // accessKey请登录https://ak-console.aliyun.com/#/查看
    public static final String accessKeyId = "LTAIHRZWfjPqwmuu";
    public static final String accessKeySecret = "u6MxT7CHlmxRKcBUkuiTSJIHosM9S6";
    public static final String bucketName = "glass-pic-info";

    public static final String url = "http://glass-pic-info.oss-cn-shenzhen.aliyuncs.com/815945fd3c65c38077e08a36ff6ed126";

    private final static String ERROR_PREFIX = "error|";

    public static final OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);

    @RequestMapping(value = "/uploadImage", method = RequestMethod.POST)
    public JsonResponse<Map<String,Object>> uploadImage(@RequestParam("file") MultipartFile multipartFile,
                              @RequestParam(required = false) Integer width,
                              @RequestParam(required = false) Integer height) {

        if (multipartFile == null) {
            return JsonResponse.invalidResp("未上传文件");//ERROR_PREFIX + Constants.SERVER_DOWN;
        }
        if (!isPic(multipartFile.getOriginalFilename())) {
            return JsonResponse.invalidResp("请确认是图片类型是否为jpg, JPG, png, PNG, jpeg, JPEG!");
        }
        if (multipartFile.getSize() > 10 * 1024 * 1024) {
            return JsonResponse.invalidResp("图片大小必须小于10M!");
        }
        if (!validatePicSize(width, height, multipartFile)) {
            return JsonResponse.invalidResp(String.format("图片尺寸错误！应大于%s*%s像素", width == null ? 0 : width, height == null ? 0 : height));
        }
        try {
            byte[] bytes = multipartFile.getBytes();
            String[] split = multipartFile.getOriginalFilename().split("\\.");
            String md5 = DigestUtils.md5Hex(bytes).toLowerCase();
            String nameKey = md5+"."+ split[split.length - 1];
            PutObjectResult putObjectResult = ossClient.putObject(bucketName,nameKey,new ByteArrayInputStream(bytes));
            if (StringUtils.isNotBlank(putObjectResult.getETag())){
                Map<String,Object> map = Maps.newHashMap();
                map.put("url",getUrl(bucketName, endpoint, nameKey));
                return JsonResponse.successResp(map);
            }
        } catch (IOException e) {
            String msg = "postImage error!";
            log.error(msg, e);
            return JsonResponse.errorResp(Constants.IMAGE_UPLOAD_FAILED);
        }

        return JsonResponse.errorResp(Constants.IMAGE_UPLOAD_FAILED);
    }

    @Data
    public static class ImageBody{
        private String file;
    }

    @RequestMapping(value = "/uploadImageBase64", method = RequestMethod.POST)
    public JsonResponse<Map<String,Object>> uploadImage(@RequestBody() ImageBody base64Str,
                                                        @RequestParam(required = false) Integer width,
                                                        @RequestParam(required = false) Integer height) {
        if (base64Str == null || base64Str.getFile() == null) {
            return JsonResponse.invalidResp("未上传文件");//ERROR_PREFIX + Constants.SERVER_DOWN;
        }

        Iterable<String> split = Splitter.on(",").trimResults().omitEmptyStrings().split(base64Str.getFile());
        List<String> images = Lists.newArrayList(split);
        if (CollectionUtils.isEmpty(images) || images.get(1) == null){
            return JsonResponse.invalidResp("未上传文件");//ERROR_PREFIX + Constants.SERVER_DOWN;
        }
        if (images.get(0) == null || !images.get(0).contains("image") || !images.get(0).contains("png")){
            return JsonResponse.invalidResp("请上传png图片");//ERROR_PREFIX + Constants.SERVER_DOWN;
        }
        String file = images.get(1);
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            byte[] bytes = decoder.decodeBuffer(file);
            String md5 = DigestUtils.md5Hex(bytes).toLowerCase();
            String nameKey = md5+".png";
            String path = saveImageLocal(nameKey,bytes);
            PutObjectResult putObjectResult = ossClient.putObject(bucketName, nameKey, new ByteArrayInputStream(bytes));
            if (StringUtils.isNotBlank(putObjectResult.getETag())){
                Map<String,Object> map = Maps.newHashMap();
                map.put("url",path);
                map.put("remoteUrl",getUrl(bucketName,endpoint,nameKey));
                return JsonResponse.successResp(map);
            }
        } catch (IOException e) {
            String msg = "postImage error!";
            log.error(msg, e);
            return JsonResponse.errorResp(Constants.IMAGE_UPLOAD_FAILED);
        }
        return JsonResponse.errorResp(Constants.IMAGE_UPLOAD_FAILED);
    }

    private String saveImageLocal(String nameKey, byte[] bytes) throws IOException {
        BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes));
        String pathname = "/usr/node/dist/uploadimage/" + nameKey;
        ImageIO.write(image, "png", new File(pathname));
        return pathname.replace("/usr/node/dist/", "");
    }

    public static String getUrl(String bucketName,String endpoint,String key) {
        String url = "http://"+ bucketName + "."+ endpoint+"/"+key;
        return url;
    }

    private boolean validatePicSize(Integer width, Integer height, MultipartFile file) {
        if (width == null && height == null) {
            return true;
        }
        int imgHeight;
        int imgWidth;
        try {
            SimpleImageInfo imageInfo = new SimpleImageInfo(file);
            imgHeight = imageInfo.getHeight();
            imgWidth = imageInfo.getWidth();
        } catch (IOException e) {
            log.error("get Pic height width error!", e);
            return false;
        }
        if (imgHeight <= 0 || imgWidth <= 0) {
            log.error("get Image size error!");
            return false;
        }
        if (width != null && imgWidth < width) {
            return false;
        }

        if (height != null && imgHeight < height) {
            return false;
        }

        return true;
    }

    private boolean isPic(String name) {
        if (StringUtils.isBlank(name)) {
            return false;
        }
        String[] img = name.split("\\.");
        return StringUtils.isNotBlank(img[img.length - 1]) && Constants.imageTypeList.contains(img[img.length - 1]);
    }
}
